package com.ys.otms.services.impl;

import com.ys.otms.constant.WxConstant;
import com.ys.otms.dao.ICompanyDao;
import com.ys.otms.dao.IUserDao;
import com.ys.otms.dto.CompanyDto;
import com.ys.otms.dto.UserDto;
import com.ys.otms.services.ILoginServices;
import com.ys.otms.utils.*;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;

@Service
public class LoginServiceImpl implements ILoginServices {

    private static Logger logger = LoggerFactory.getLogger(LoginServiceImpl.class);

    @Autowired
    private IUserDao iUserDao;

    @Autowired
    private ICompanyDao iCompanyDao;

    @Override
    public JSONObject loginV(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        JSONObject retObj = new JSONObject();
        logger.info("LoginServiceImpl loginV start obj:{}", obj);

        String phoneNum = JsonUtil.getJSONObjectString(obj, "phoneNum");
        String verification = JsonUtil.getJSONObjectString(obj, "verification");
        if (StringUtil.isEmpty(phoneNum) || StringUtil.isEmpty(verification)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "手机号或验证码不能为空");
            return retObj;
        }
        UserDto qryUser = new UserDto();
        qryUser.setPhoneNum(phoneNum);
        qryUser.setVerification(verification);
        List<UserDto> userDtoList = iUserDao.queryUser(qryUser);

        if (ListUtil.isEmpty(userDtoList)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "手机号或验证码错误");
        } else {
            UserDto dto = userDtoList.get(0);
            HttpSession session = request.getSession();

            setSession(session, dto);

            //删除verification，防止一直用这个来登录,登录的时候要进行为空判断
            dto.setVerification("");
            iUserDao.updateUser(dto);

            setLoginReturn(retObj, dto);
        }
        return retObj;
    }

    @Override
    public JSONObject loginP(HttpServletRequest request, HttpServletResponse response, JSONObject obj) {
        JSONObject retObj = new JSONObject();
        logger.info("LoginServiceImpl loginP start obj:{}", obj);
        String password = JsonUtil.getJSONObjectString2(obj, "password");
        String account = JsonUtil.getJSONObjectString2(obj, "account");
        String rememberPassword = JsonUtil.getJSONObjectString2(obj, "rememberPassword");

        if (StringUtil.isEmpty(account) || StringUtil.isEmpty(password)) {
            Cookie[] cookies = request.getCookies();
            if (null != cookies) {
                for (Cookie cookie : cookies) {
                    if ("ys_user".equals(cookie.getName())) {
                        String value = cookie.getValue();
                        value = EncryptionUtil.jdkBase64Decode(value);
                        String[] valueArr = value.split("&#&");
                        if (2 == valueArr.length) {
                            account = valueArr[0];
                            password = valueArr[1];
                        }
                    }
                }
            }
            if (StringUtil.isEmpty(account)) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "请输入账号密码");
            } else {
                loginP(request, response, account, password, retObj, rememberPassword);
            }

        } else {
            loginP(request, response, account, password, retObj, rememberPassword);
        }
        return retObj;
    }

    private void loginP(HttpServletRequest request, HttpServletResponse response, String account, String password, JSONObject retObj, String rememberPassword) {
        UserDto qryUser = new UserDto();
        qryUser.setAccount(account);
        qryUser.setPassword(password);
        List<UserDto> userDtoList = iUserDao.queryUser(qryUser);

        if (ListUtil.isEmpty(userDtoList)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "账号或密码错误");
        } else {
            UserDto userDto = userDtoList.get(0);
            checkPhoneFreeze(retObj, userDto);
            if (retObj.getBoolean("SUCCESS")) {
                HttpSession session = request.getSession();
                setSession(session, userDto);
                setLoginReturn(retObj, userDto);
//                addCookie(response, account, password, rememberPassword);
            }
        }
    }

    private void addCookie(HttpServletResponse response, String account, String password, String rememberPassword) {
        if (StringUtil.isNotEmpty(rememberPassword) && "Y".equals(rememberPassword)) {
            String value = account + "&#&" + password;
            Cookie cookie = new Cookie("ys_user", EncryptionUtil.jdkBase64Encode(value));
            cookie.setMaxAge(30 * 60);// 设置为30min
            cookie.setPath("/otms2");
//            cookie.setDomain();
            response.addCookie(cookie);
        }
    }

    @Override
    public JSONObject loginCallBack(HttpServletRequest request) throws Exception {
        String code = JsonUtil.getJSONObject(request).getString("code");
        logger.info("loginCallBack code:{}", code);
        JSONObject retObj = new JSONObject();
        if (StringUtil.isEmpty(code)) {
            retObj.put("state", "false");
            retObj.put("msg", "用户禁止授权！");
            return retObj;
        }

        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        url = url.replaceAll("APPID", WxConstant.APP_ID).replaceAll("SECRET", WxConstant.APP_SECRET).replaceAll("CODE", code);
        JSONObject jsonObject = HttpUtil.get(url);
        String openId = JsonUtil.getJSONObjectString(jsonObject, "openid");
        String unionId = JsonUtil.getJSONObjectString(jsonObject, "unionid");
        logger.info("LoginServiceImpl loginCallBack start jsonObject:{}", jsonObject);
        if (StringUtil.isEmpty(unionId)) {
            String errCode = jsonObject.getString("errcode");
            String errMsg = jsonObject.getString("errmsg");
            logger.error("loginCallBack fail get Open Id errCode:{},errMsg:{}", errCode, errMsg);
            retObj.put("state", "false");
            retObj.put("msg", "获取unionId出错！");
            return retObj;
        }
        UserDto qryUser = new UserDto();
        qryUser.setUnionId(unionId);
        List<UserDto> userDtoList = iUserDao.queryUser(qryUser);
        if (ListUtil.isEmpty(userDtoList)) {
            logger.info("ListUtil.isEmpty(userDtoList)");
            //插入
            UserDto userDto = new UserDto();
            userDto.setWxOpenId(openId);
            userDto.setUnionId(unionId);
            iUserDao.insertUser(userDto);
            request.getSession().setAttribute("SESSION_WX_OPEN_ID", openId);
            request.getSession().setAttribute("SESSION_UNION_ID", unionId);
            retObj.put("state", "noBind");
            retObj.put("msg", "没有和账号绑定！");
            return retObj;
        } else {
            UserDto dto = userDtoList.get(0);
            if (StringUtil.isNotEmpty(dto.getAccount())) {
                logger.info("StringUtil.isNotEmpty(dto.getAccount())");
                //说明存在了直接登录进去
                if (4 == dto.getRoleId() && StringUtil.isEmpty(dto.getEndTime())) {
                    dto.setEndTime(DateUtil.date2String(DateUtil.offsetDay(new Date(), 7), DateUtil.DATETIME_FORMAT_1));
                    iUserDao.updateUser(dto);
                }
                if (StringUtil.isNotEmpty(dto.getEndTime())) {
                    int result = DateUtil.compare(new Date(), DateUtil.string2Date(dto.getEndTime(), DateUtil.DATETIME_FORMAT_1));
                    if (2 == result) {
                        retObj.put("MSG", "登录失败！过了7天试用期！");
                        retObj.put("SUCCESS", false);
                        return retObj;
                    }
                }
                HttpSession session = request.getSession();
                session.setAttribute("SESSION_USER_ID", dto.getId().toString());
                session.setAttribute("SESSION_ROLE_ID", dto.getRoleId());
                session.setAttribute("SESSION_COMPANY_ID", dto.getCompany());
                session.setAttribute("SESSION_PHONE_NUM", dto.getPhoneNum());
                session.setAttribute("SESSION_WX_OPEN_ID", dto.getWxOpenId());
                session.setAttribute("SESSION_UNION_ID", dto.getUnionId());
                session.setAttribute("SESSION_WX_BIND", StringUtil.isEmpty(dto.getUnionId()) ? "N" : "Y");
                retObj.put("SUCCESS", true);
                return retObj;
            } else {
                //有数据，但是没有进行绑定
                request.getSession().setAttribute("SESSION_WX_OPEN_ID", openId);
                request.getSession().setAttribute("SESSION_UNION_ID", unionId);
                retObj.put("state", "noBind");
                retObj.put("msg", "没有和账号绑定！");
                return retObj;
            }
        }
    }

    @Override
    @Transactional
    public JSONObject wxLoginBind(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        JSONObject retObj = new JSONObject();
        String wxOpenId = (String) request.getSession().getAttribute("SESSION_WX_OPEN_ID");
        String unionId = (String) request.getSession().getAttribute("SESSION_UNION_ID");
        logger.info("LoginServiceImpl wxLoginBind start obj:{},wxOpenId:{},unionId:{}", obj, wxOpenId, unionId);

        String account = JsonUtil.getJSONObjectString(obj, "account");
        String password = JsonUtil.getJSONObjectString(obj, "password");
        String phoneNum = JsonUtil.getJSONObjectString(obj, "phoneNum");
        String verification = JsonUtil.getJSONObjectString(obj, "verification");
        UserDto qryUser = new UserDto();
        if (StringUtil.isNotEmpty(account)) {
            qryUser.setAccount(account);
            qryUser.setPassword(password);
        } else {
            //todo 发送短信弄一个标识，区分是哪个功能发送短信，绑定微信的短信，先要判断手机号是否存在，不存在不能进行绑定（不然就会自动创建试用账号并绑定了，这个要确认一下）
            qryUser.setPhoneNum(phoneNum);
            qryUser.setVerification(verification);
        }

        List<UserDto> userDtoList = iUserDao.queryUser(qryUser);
        if (ListUtil.isEmpty(userDtoList)) {
            retObj.put("msg", "绑定失败，请输入正确的信息！");
            retObj.put("success", "false");
            return retObj;
        }
        UserDto dto = userDtoList.get(0);
        dto.setWxOpenId(wxOpenId);
        dto.setUnionId(unionId);
        iUserDao.updateUser(dto);

        dto = new UserDto();
        dto.setWxOpenId(wxOpenId);
        iUserDao.deleteUser(dto);

        HttpSession session = request.getSession();
        session.setAttribute("SESSION_USER_ID", dto.getId().toString());
        session.setAttribute("SESSION_ROLE_ID", dto.getRoleId());
        session.setAttribute("SESSION_COMPANY_ID", dto.getCompany());
        session.setAttribute("SESSION_COMPANY_NAME", dto.getCompanyName());
        if (4 == dto.getRoleId()) {
            session.setAttribute("SESSION_COMPANY_NAME", "");
        }
        session.setAttribute("SESSION_PHONE_NUM", dto.getPhoneNum());
        session.setAttribute("SESSION_WX_OPEN_ID", dto.getWxOpenId());
        session.setAttribute("SESSION_UNION_ID", dto.getUnionId());
        session.setAttribute("SESSION_NICK_NAME", dto.getAccount());
        session.setAttribute("SESSION_WX_BIND", StringUtil.isEmpty(dto.getUnionId()) ? "N" : "Y");
        retObj.put("MSG", "绑定成功！");
        retObj.put("SUCCESS", true);
        return retObj;
    }

    @Override
    //忘记密码
    public JSONObject forgetPassword(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        JSONObject retObj = new JSONObject();
        logger.info("LoginServiceImpl forgetPassword start obj:{}", obj);
        String phoneNum = JsonUtil.getJSONObjectString(obj, "phoneNum");
        String verification = JsonUtil.getJSONObjectString(obj, "verification");
        String password = JsonUtil.getJSONObjectString(obj, "password");

        UserDto qryUser = new UserDto();
        qryUser.setPhoneNum(phoneNum);
        qryUser.setVerification(verification);
        List<UserDto> userDtoList = iUserDao.queryUser(qryUser);
        if (ListUtil.isEmpty(userDtoList)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "验证码错误");
        } else {
            UserDto userDto = userDtoList.get(0);
            userDto.setPassword(password);
            userDto.setVerification("");
            iUserDao.updateUser(userDto);
            retObj.put("SUCCESS", true);
            retObj.put("MSG", "密码修改成功！");
        }

        return retObj;
    }

    @Override
    @Transactional
    //发送验证码
    public JSONObject sendVerification(HttpServletRequest request) throws Exception {

        JSONObject obj = JsonUtil.getJSONObject(request);
        JSONObject retObj = new JSONObject();
        logger.info("LoginServiceImpl sendVerification4Login start obj:{}", obj);
        String phoneNum = JsonUtil.getJSONObjectString(obj, "phoneNum");
        String fromStr = JsonUtil.getJSONObjectString(obj, "from");
        int from = Integer.parseInt(fromStr);
        switch (from) {
            case 1:
                //注册
                retObj = sendVerification4Register(phoneNum);
                break;
            case 2:
                //登录
                retObj = sendVerification(phoneNum);
                break;
            case 3:
                //忘记密码
                retObj = sendVerification(phoneNum);
                break;
        }

        return retObj;
    }

    public JSONObject sendVerification(String phoneNum) {
        UserDto qryDto = new UserDto();
        qryDto.setPhoneNum(phoneNum);
        JSONObject retObj = new JSONObject();
        List<UserDto> userDtoList = iUserDao.queryAllUser(qryDto);
        if (ListUtil.isEmpty(userDtoList)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "该手机号尚未注册");
        } else {
            UserDto userDto = userDtoList.get(0);

            checkPhoneFreeze(retObj, userDto);

            if (retObj.getBoolean("SUCCESS")) {
                //发送登录验证码
                String verification = StringUtil.getRandomNumber(4);
                retObj = sendSmS(phoneNum, "SMS_151515175", verification);
                if (retObj.getBoolean("SUCCESS")) {
                    userDto.setVerification(verification);
                    iUserDao.updateUser(userDto);
                }
            }
        }
        return retObj;
    }

    //检查手机号是否冻结
    private void checkPhoneFreeze(JSONObject retObj, UserDto userDto) {
        retObj.put("SUCCESS", true);
        if (2 == userDto.getStatus()) {
            retObj.put("MSG", "该手机号已冻结");
            retObj.put("SUCCESS", false);
        }
        if (StringUtil.isNotEmpty(userDto.getEndTime()) && 4 == userDto.getRoleId()) {
            int result = DateUtil.compare(new Date(), DateUtil.string2Date(userDto.getEndTime(), DateUtil.DATETIME_FORMAT_1));
            if (2 == result) {
                retObj.put("MSG", "该手机号已冻结");
                retObj.put("SUCCESS", false);
                //修改状态
                userDto.setStatus(2);
                iUserDao.updateUser(userDto);
            }
        }
    }

    @Transactional
    public JSONObject sendVerification4Register(String phoneNum) {
        logger.info("LoginServiceImpl sendVerification4Register start phoneNum:{}", phoneNum);
        UserDto qryUser = new UserDto();
        qryUser.setPhoneNum(phoneNum);
        List<UserDto> list = iUserDao.queryUser4Verification(qryUser);
        JSONObject retObj = new JSONObject();
        String verification = StringUtil.getRandomNumber(4);
        if (ListUtil.isEmpty(list)) {
            //没有这个手机号的用户，先插入手机号和验证码
            UserDto userDto = new UserDto();
            userDto.setAccount(phoneNum);
            userDto.setVerification(verification);
            userDto.setStatus(3);
            CompanyDto companyDto = new CompanyDto();
            companyDto.setCompanyName("彦思科技_" + phoneNum);
            companyDto.setMobilePhone(phoneNum);
            //插入虚拟的company
            iCompanyDao.insertCompany(companyDto);
            userDto.setCompany(companyDto.getCompanyId().toString());
            userDto.setPhoneNum(phoneNum);
            iUserDao.insertUser(userDto);
            userDto.setRoleId(4);
            //插入对应的角色，4表示试用角色
            iUserDao.insertUserRole(userDto);
            retObj = sendSmS(phoneNum, "SMS_151515175", verification);
            if (!retObj.getBoolean("SUCCESS")) {
                throw new RuntimeException("发送验证码失败，请联系管理员");
            }
        } else {
            UserDto userDto = list.get(0);
            if (3 == userDto.getStatus()) {
                //已经发送给验证码，但是还未注册，号码已存在我们数据库
                retObj = sendSmS(phoneNum, "SMS_151515175", verification);
                if (retObj.getBoolean("SUCCESS")) {
                    userDto.setVerification(verification);
                    iUserDao.updateUser(userDto);
                }
            } else {
                //表示已经注册
                checkPhoneFreeze(retObj, userDto);
                if (retObj.getBoolean("SUCCESS")) {
                    retObj.put("MSG", "该手机号已存在");
                    retObj.put("SUCCESS", false);
                }
            }
        }
        return retObj;
    }

    @Override
    public JSONObject register(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("LoginServiceImpl register start obj:{}", obj);
        String phoneNum = JsonUtil.getJSONObjectString(obj, "phoneNum");
        String verification = JsonUtil.getJSONObjectString(obj, "verification");
        String password = JsonUtil.getJSONObjectString(obj, "password");
        String flag = JsonUtil.getJSONObjectString(obj, "flag");
        JSONObject retObj = new JSONObject();
        if (StringUtil.isEmpty(phoneNum) || StringUtil.isEmpty(verification) || StringUtil.isEmpty(password)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "注册信息不能为空！");
            return retObj;
        }
        if ("Y".equalsIgnoreCase(flag)) {
            UserDto userDto = new UserDto();
            userDto.setPhoneNum(phoneNum);
            userDto.setVerification(verification);
            List<UserDto> list = iUserDao.queryUser4Verification(userDto);
            if (ListUtil.isEmpty(list)) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "手机号或验证码输入错误");
            } else {
                userDto = list.get(0);
                userDto.setPassword(password);
                userDto.setStatus(0);
                userDto.setVerification("");
                iUserDao.updateUser(userDto);
                retObj.put("SUCCESS", true);
                retObj.put("MSG", "注册成功");
            }
        } else {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "请选择我同意《汇找船平台注册协议》");
        }

        return retObj;
    }

    @Override
    public JSONObject get7Days(HttpServletRequest request) {
        int userId = Integer.parseInt((String) request.getSession().getAttribute("SESSION_USER_ID"));
        int roleId = (int) request.getSession().getAttribute("SESSION_ROLE_ID");
        JSONObject retObj = new JSONObject();
        if (4 == roleId) {
            UserDto userDto = new UserDto();
            userDto.setId(userId);
            List<UserDto> list = iUserDao.queryUser(userDto);
            userDto = list.get(0);
            if (StringUtil.isNotEmpty(userDto.getEndTime())) {
                retObj.put("SUCCESS", true);
                retObj.put("MSG", "恭喜您已经成为我们重要的用户之一，试用期到：" + userDto.getEndTime() + "结束，为了您更好的体验，请上传相关企业信息");
                return retObj;
            }
            userDto.setEndTime(DateUtil.date2String(DateUtil.offsetDay(new Date(), 7), DateUtil.DATETIME_FORMAT_1));
            iUserDao.updateUser(userDto);
            retObj.put("SUCCESS", true);
            retObj.put("MSG", "恭喜您成为我们重要的用户之一，试用期为7天，为了您更好的体验，请上传相关企业信息");
            return retObj;
        }
        retObj.put("SUCCESS", true);
        retObj.put("MSG", "恭喜您成为我们重要的用户之一");
        return retObj;
    }

    private JSONObject sendSmS(String phoneNum, String templateCode, String verification) {
        JSONObject obj = new JSONObject();
        obj.put("phoneNumbers", phoneNum);
        obj.put("signName", "汇找船");
        obj.put("templateCode", templateCode);
        obj.put("templateParam", "{\"code\":" + verification + "}");
        logger.info("LoginServiceImpl sendVerification phoneNum:{},verification:{}", phoneNum, verification);
        System.out.println("verification : " + verification);
        obj = SMSUtil.SendEmail(obj);
        System.out.println("obj : " + obj);
        JSONObject retObj = new JSONObject();
        if ("N".equals(obj.getString("OK"))) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "短信发送失败！");
            return retObj;
        }
        retObj.put("SUCCESS", true);
        retObj.put("MSG", "短信发送成功！");
        return retObj;
    }

    private void setSession(HttpSession session, UserDto dto) {
        session.setAttribute("SESSION_USER_ID", dto.getId().toString());
        session.setAttribute("SESSION_ROLE_ID", dto.getRoleId());
        session.setAttribute("SESSION_COMPANY_ID", dto.getCompany());
        session.setAttribute("SESSION_COMPANY_NAME", dto.getCompanyName());
        if (4 == dto.getRoleId()) {
            session.setAttribute("SESSION_COMPANY_NAME", "");
        }
        session.setAttribute("SESSION_PHONE_NUM", dto.getPhoneNum());
        session.setAttribute("SESSION_UNION_ID", dto.getUnionId());
        session.setAttribute("SESSION_NICK_NAME", dto.getAccount());

        if (dto.getRoleId() == 3) {
            session.setAttribute("SESSION_IS_MANAGER", "N");
        } else if ((dto.getRoleId() == 1 || (dto.getRoleId() == 2))) {
            session.setAttribute("SESSION_IS_MANAGER", "Y");
        } else {
            session.setAttribute("SESSION_IS_MANAGER", "S");
        }
        session.setAttribute("SESSION_WX_BIND", StringUtil.isEmpty(dto.getUnionId()) ? "N" : "Y");
    }

    private void setLoginReturn(JSONObject retObj, UserDto userDto) {
        retObj.put("MSG", "成功登录！");
        retObj.put("SUCCESS", true);
//        retObj.put("wx_bind", StringUtil.isEmpty(userDto.getUnionId()) ? "N" : "Y");
//        retObj.put("account", userDto.getAccount());
        retObj.put("video_is_over", "Y");

        //todo 暂时不管，等下做的时候确定是所有第一次登录的人还是自己注册的人看视频
        if (4 == userDto.getRoleId() && StringUtil.isEmpty(userDto.getEndTime())) {
            retObj.put("video_is_over", "N");
        }
    }
}
